package com.ipay.common;

import com.ipay.utils.MD5;
import com.ipay.utils.MapUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * 使用bouncycastle扩展包进行base64为编码
 * @kongqz
 * **/
public class Base64Coder {


    public final static String ENCODING="UTF-8";
    /***
     * 进行base64编码
     * @param data 要编码的数据
     * @return 编码后的数据
     * */
    public static String encode(String data) throws Exception{

        Security.addProvider(new BouncyCastleProvider());

        byte[] b =Base64.encode(data.getBytes(ENCODING));
        return new String(b,ENCODING);
    }

    /**
     * 进行Base64解码
     * @param data 待解码数据
     * @return 解码后的数据
     * */
    public static String decode(String data) throws Exception{

        Security.addProvider(new BouncyCastleProvider());

        byte[] b=Base64.decode(data.getBytes(ENCODING));
        return new String(b,ENCODING);
    }


    /*
    digit固定值：128, 192或256
     */
    public static String key(int digit) {
        try {
            KeyGenerator kg = KeyGenerator.getInstance("AES");
            kg.init(digit);
            //要生成多少位，只需要修改这里即可128, 192或256
            SecretKey sk = kg.generateKey();
            byte[] b = sk.getEncoded();
            String key = byteToHexString(b);
            return key;
        } catch (NoSuchAlgorithmException e) {
            System.out.println("没有此算法。");
            return "";
        }
    }
    /**
     * byte数组转化为16进制字符串
     * @param bytes
     * @return
     */
    private static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String strHex=Integer.toHexString(bytes[i]);
            if(strHex.length() > 3) {
                sb.append(strHex.substring(6));
            } else {
                if(strHex.length() < 2) {
                    sb.append("0" + strHex);
                } else {
                    sb.append(strHex);
                }
            }
        }
        return sb.toString();
    }

    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        System.out.println(Base64Coder.key(128));///128, 192或256
        System.out.println(Base64Coder.key(192));///128, 192或256
        System.out.println(Base64Coder.key(192));///128, 192或256
        System.out.println(Base64Coder.key(256));///128, 192或256

        String parameter= Base64Coder.encode("D2017103112000000012");
        System.out.println(parameter);
        String parameter2= Base64Coder.encode("阿里巴巴1D2017103112000000012");
        System.out.println(parameter2);

        String tmp = "codeNo=20170919919103&merchantNo=D2017091910000000008&notifyUrl=notifyUrl&payMoney=20&sponsorOrderNo=D2017091910000001234";
        System.out.println("原文："+tmp);
        String code=Base64Coder.encode(tmp);
        System.out.println("编码后："+code);
        System.out.println("解码后："+Base64Coder.decode(code));

        Map<String,String> map=new HashMap<String,String>();
        map.put("merchantNo","D2017091910000000008");
        map.put("codeNo","20170919919103");
        map.put("sponsorOrderNo", "D2017091910000001234");
        map.put("payMoney","20");
        map.put("notifyUrl","notifyUrl");
        String strtosign = MapUtils.formatUrlMap(map, false, false);
        System.out.println("=====:"+strtosign);
        String base64_strtosign = Base64Coder.encode(strtosign);
        System.out.println("加密：" + base64_strtosign);
        System.out.println("解密：" + Base64Coder.decode(base64_strtosign));
        //TODO 查询商户相关数据  =payKey
        String signstr = MD5.sign(strtosign, "&key=key", "utf-8");
        System.out.println("-----:"+signstr);
    }
}